package com.llbnk.srb.core.controller.api;

import com.alibaba.fastjson.JSON;
import com.llbnk.common.result.R;
import com.llbnk.srb.core.hfb.RequestHelper;
import com.llbnk.srb.core.pojo.vo.UserBindVO;
import com.llbnk.srb.core.service.UserBindService;
import com.llbnk.srb.core.util.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author shkstart
 * @create 2022-04-16 12:03
 */
@Api(tags = "会员账号绑定")
@RestController
@RequestMapping("/api/core/userBind")
@Slf4j
public class UserBindController {

    @Resource
    private UserBindService userBindService;//用户绑定表 服务类


    @ApiOperation("账户绑定提交数据")
    @PostMapping("/auth/bind")
    public R bind(@RequestBody UserBindVO userBindVO , HttpServletRequest request){

        //header中获取token，并对token进行校验，确保用户已经登录，并错token中取出userId
        //生成token是在UserInfoController的login里面
        //login  ->  UserInfoVO userInfoVO = userInfoService.login(loginVO,ip);
        //userInfoService.login -> String token = JwtUtils.createToken(userInfo.getId(), userInfo.getName());
        //所以我们当时在登录的时候就放入了userInfo的userId所以我们还是有办法获取出来的,通过HttpServletRequest
        String token = request.getHeader("token");
        //JwtUtils.getUserId对token进行校验然后获取userId
        Long userId = JwtUtils.getUserId(token);
        System.out.println("*****************************");
        System.out.println(token);
        System.out.println("*****************************");
        //根据userId做账户绑定
        //因为最终生成要生成一个.html表单交给前端,所以我们要生成一个动态表单的字符串
        String formStr = userBindService.commitBindUser(userBindVO,userId);
        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
        System.out.println(formStr);
        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
        return R.ok().data("formStr", formStr);
    }


    /**
     * 异步通知实现
     * 汇付平台会向我们的商户平台发起请求，汇付平台会向我们的商户平台的地址是一开始
     * 我们告诉了汇付平台，在UserBindServiceImpl中的bind方法中的
     * paramMap.put("notifyUrl", HfbConst.USERBIND_NOTIFY_URL);就是告诉汇付平台
     * 一会回调请求这个USERBIND_NOTIFY_URL地址（http://localhost/api/core/userBind/notify）
     * 需要绑定成功才行，怎么才算绑定成功？srb的user_info和hfb的user_bind需要关联，
     * 通过user_code把他们关联起来，把srb的user_info中的bind_code和
     * hfb的user_bind中的bind_code字段关联上，并且修改srb的user_info中bind_status
     * 和srb的user_bind中的status，bind_code。
     * srb就需要进行绑定处理，也就是修改这些表的数据。
     */
    @ApiOperation("账户绑定异步回调")
    @PostMapping("/notify")
    //hfb给srb发起一个请求，要求srb必须发一个字符串为success才证明回调成功
    public String notify(HttpServletRequest request) {
        //HttpServletRequest是接受hfb给srb发起一个请求，hfb发的也是一个form，具体看3.3.4同步返回/异步通知
        //D:\学习类\java\金融项目--尚融宝\资料（ziw文件使用为知笔记打开）\资料\04第四部分\汇付宝

        //将hfb的文件Map<String, String[]>转化成Map<String, Object>
        Map<String, Object> paramMap = RequestHelper.switchMap(request.getParameterMap());
        log.info("账户绑定异步回调接受的参数如下："+ JSON.toJSONString(paramMap));

        /**
         * 如果srb要是给hfb发请求，srb就需要带一个sign签名，hfb就需要进行签名校验
         * 上面代码进行的是hfb给srb发请求，hfb发请求也是带签名过来的，srb也需要做签名校验
         * 签名校验成功了在做修改信息 user_info user_bind
         */

        //验签  其实就是将传回来的账户绑定异步回调接受的参数
        //agentUserId resultCode bindCode resultMsg timestamp经过计算然后看看得出来的sign和回调参数中的sign是一个不
        if(!RequestHelper.isSignEquals(paramMap)){
            log.error("用户账号绑定异步回调签名验证错误："+ JSON.toJSONString(paramMap));
            //这个是返回hfb的
            return "fail";
        }
        log.info("眼前成功！开始账户绑定");

        //账户同步操作 修改相关数据库
        userBindService.notify(paramMap);

        return "success";
    }

}
